package com.douyang.service.impl;


import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.douyang.VO.MessageVO;
import com.douyang.VO.UserInfoVO;
import com.douyang.utils.EmailUtils;
import com.douyang.utils.IPUtil;
import com.douyang.base.utils.IdWorkerUtils;
import com.douyang.dto.LoginDTO;
import com.douyang.base.expcetion.UserException;
import com.douyang.dto.SendMessageDTO;
import com.douyang.mapper.UserBaseInfoMapper;
import com.douyang.base.model.UserBaseInfo;
import com.douyang.pojo.*;
import com.douyang.service.*;
import com.douyang.base.utils.UserUtil;
import com.douyang.utils.FluxFactory;
import jakarta.servlet.http.HttpServletRequest;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Lazy;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import reactor.core.publisher.Flux;

import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
import java.util.concurrent.TimeUnit;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author xiaoma
 * @since 2025-03-01
 */
@Service
public class UserBaseInfoServiceImpl extends ServiceImpl<UserBaseInfoMapper, UserBaseInfo> implements UserBaseInfoService {
    @Autowired
    private ApplicationContext applicationContext;

    @Autowired
    @Lazy
    private UserFollowedService userFollowedService;

    @Autowired
    @Lazy
    private UserVideoLikedService userVideoLikedService;

    @Autowired
    RedisTemplate<String,Object> redisTemplate;

    @Autowired
    StringRedisTemplate stringRedisTemplate;

    @Autowired
    SystemQuestionAnswerService systemQuestionAnswerService;

    @Autowired
    FluxFactory fluxFactory;

    @Autowired
    EmailUtils emailUtils;

    @Override
    public UserBaseInfo doLogin(LoginDTO loginDTO) {
        AuthService authService = applicationContext.getBean(loginDTO.getType(), AuthService.class);
        return authService.execute(loginDTO);
    }

    @Override
    public UserInfoVO getUserInfo(Long userId) {
        UserBaseInfo userBaseInfo;
        if (userId == null) {
            userBaseInfo = UserUtil.getLoginUserBaseInfo();
        }else{
            userBaseInfo = lambdaQuery().eq(UserBaseInfo::getId, userId).one();
        }
        if (userBaseInfo == null) {throw new UserException("无此id");}
        UserInfoVO userInfoVO = new UserInfoVO();
        BeanUtils.copyProperties(userBaseInfo,userInfoVO);
        userInfoVO.setFollowedCount(
                userFollowedService.lambdaQuery()
                        .eq(UserFollowed::getFollowedUserId,userBaseInfo.getId())
                        .count()
        );

        userInfoVO.setLikeCount(
                userVideoLikedService.lambdaQuery()
                        .eq(UserVideoLiked::getUserId,userBaseInfo.getId())
                        .count()
        );
        return userInfoVO;
    }

    @Override
    public List<MessageVO> getMessageList() {
        UserBaseInfo loginUserBaseInfo = UserUtil.getLoginUserBaseInfo();
        try {
            List<Object> messageListObject = redisTemplate.opsForList().range("message_list:" + loginUserBaseInfo.getId(), 0, -1);
            if(CollectionUtils.isEmpty(messageListObject)){
                return List.of();
            }

            return messageListObject.stream()
                    .map(message -> {
                        MessageVO messageVO = new MessageVO();
                        BeanUtils.copyProperties(message, messageVO);
                        return messageVO;
                    }).toList();
        }catch (Exception e){
            e.printStackTrace();
            return List.of();
        }
    }

    @Override
    public MessageVO sendMessage(SendMessageDTO sendMessageDTO) {
        UserBaseInfo loginUserBaseInfo = UserUtil.getLoginUserBaseInfo();
        Message message=new Message();
        BeanUtils.copyProperties(sendMessageDTO,message);
        message.setAvatar(sendMessageDTO.getSystem()?"1.png":loginUserBaseInfo.getAvatar() );
        redisTemplate.opsForList().rightPush("message_list:" + loginUserBaseInfo.getId(), message);
        // 2. 修剪列表，只保留最后 10 个元素（即索引 -10 到 -1）
        redisTemplate.opsForList().trim("message_list:" + loginUserBaseInfo.getId(), -10, -1);


        MessageVO messageVO = new MessageVO();
        BeanUtils.copyProperties(message,messageVO);
        return messageVO;
    }

    @Override
    public Flux<String> getAIAnswerByStream(String model) {
        if(StringUtils.isEmpty(model))throw new UserException("参数异常");
        List<DeepSeekMessage> systemList = new ArrayList<>();
        systemList.add(DeepSeekMessage.builder().role("system").content("请使用中文输出").build());
        systemList.add(DeepSeekMessage.builder().role("system").content("现在，你是抖阳平台智能客服，请回答用户问题").build());
        List<SystemQuestionAnswer> systemQuestionAnswers = systemQuestionAnswerService.lambdaQuery().list();
        if(!CollectionUtils.isEmpty(systemQuestionAnswers)){
            systemList.add(DeepSeekMessage.builder().role("system").content("以下是一些可能遇到的问题及其答案，如果命中问题，回复一个结构清晰、详细且友好的答案").build());

            systemList.addAll(systemQuestionAnswers
                    .stream()
                    .map(sqa-> DeepSeekMessage.builder()
                            .role("system")
                            .content("问题："+sqa.getQuestion()+"回答："+sqa.getAnswer())
                            .build()).toList()
            );
        }

        return fluxFactory.flux(systemList,model);
    }

    @Override
    public void clearChat() {
        UserBaseInfo loginUserBaseInfo = UserUtil.getLoginUserBaseInfo();
        redisTemplate.delete("message_list:"+loginUserBaseInfo.getId());
    }

    @Override
    public void getCode(HttpServletRequest request,String email) {
        String emailPattern = "^[A-Za-z0-9+_.-]+@[A-Za-z0-9.-]+$";
        Pattern pattern = Pattern.compile(emailPattern);
        Matcher matcher = pattern.matcher(email);
        if(!matcher.matches())throw new UserException("请输入正确邮箱");

        String ipAddr = IPUtil.getIpAddr(request);
        if(Boolean.TRUE.equals(stringRedisTemplate.hasKey("code:" + email)) || Boolean.TRUE.equals(redisTemplate.hasKey("ipVis:" + ipAddr)))throw new UserException("上一个验证码尚未过期，请等待");
        String code = UUID.randomUUID().toString().substring(0, 4);
        stringRedisTemplate.opsForValue().set("code:"+email,code,60, TimeUnit.SECONDS);
        stringRedisTemplate.opsForValue().set("ipVis:"+ipAddr,ipAddr,60, TimeUnit.SECONDS);
        new Thread(() -> emailUtils.sendToEmail(email,"欢迎注册抖阳短视频平台，您的验证码为["+code+"]，打死不要告诉别人哦，验证码30秒有效","抖阳邮箱验证")).start();
    }
}
